package org.insist.best.codeGenerator.dao;

import cn.hutool.core.util.StrUtil;
import cn.hutool.db.DbUtil;
import cn.hutool.db.sql.SqlExecutor;
import cn.hutool.db.sql.SqlUtil;
import cn.hutool.json.JSONObject;
import org.insist.best.codeGenerator.core.DbConfig;
import org.insist.best.codeGenerator.vo.ColumnListItem;
import org.insist.best.codeGenerator.vo.TableListItem;

import java.sql.Connection;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class MysqlDao extends DataBaseInfoDao {

    private TableListItemMapper tableListItemMapper = new TableListItemMapper();

    private ColumnListItemMapper columnListItemMapper = new ColumnListItemMapper();


    public MysqlDao(DbConfig dbConfig) {
        super(dbConfig);
    }

    @Override
    public Map<String, String> tableInfo(String tableName) {
        return null;
    }

    @Override
    public JSONObject queryList(String queryTableName, int page, int pageSize) {
        Connection connection = null;
        StringBuilder countSql = new StringBuilder("select count(1) from information_schema.tables \n");
        StringBuilder querySql = new StringBuilder("select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables \n");
        StringBuilder whereSql = new StringBuilder("where table_schema = (select database()) \n");
        if (StrUtil.isNotBlank(queryTableName)) {
            whereSql.append("and table_name like concat('%','").append(queryTableName).append("', '%') \n");
        }
        whereSql.append("order by table_name desc \n");
        int startPage = (page - 1) * pageSize;
        List<TableListItem> listItems = new ArrayList<>();
        int count = 0;
        try {
            connection = getConnection();
            ResultSet countResultSet = SqlExecutor.callQuery(connection, countSql.append(whereSql).toString());
            if (countResultSet.next()) {
                count = countResultSet.getInt("count(1)");
            }
            String sql = querySql
                    .append(whereSql)
                    .append(String.format(" limit %d, %d ", startPage, pageSize)).toString();
            ResultSet resultSet = SqlExecutor.callQuery(connection, sql);
            while (resultSet.next()) {
                TableListItem item = tableListItemMapper.mapRow(resultSet);
                listItems.add(item);
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DbUtil.close(connection);
        }
        JSONObject result = new JSONObject();
        result.set("count", count);
        result.set("list", listItems);
        return result;
    }

    @Override
    public TableListItem queryTable(String tableName) {
        String sql = "select table_name tableName, engine, table_comment tableComment, create_time createTime from information_schema.tables where table_name = '" + tableName + "'";
        Connection connection = null;
        try {
            connection = getConnection();
            ResultSet resultSet = SqlExecutor.callQuery(connection, sql);
            if (resultSet.next()) {
                return tableListItemMapper.mapRow(resultSet);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DbUtil.close(connection);
        }
        return new TableListItem();
    }

    @Override
    public List<ColumnListItem> queryColumns(String tableName) {
        String sql =
                "select column_name columnName, data_type dataType, column_comment columnComment, column_key columnKey, extra from information_schema.columns\n" +
                        " \t\t\twhere table_name = '" + tableName + "' and table_schema = (select database()) order by ordinal_position";
        Connection connection = null;
        List<ColumnListItem> columnListItems = new ArrayList<>();
        try {
            connection = getConnection();
            ResultSet resultSet = SqlExecutor.callQuery(connection, sql);
            while (resultSet.next()) {
                columnListItems.add(columnListItemMapper.mapRow(resultSet));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return columnListItems;
    }
}
